#!/bin/bash

###############
# Generate a linker script for GNU ld.
#
#
#



error () {
    echo "error: $*" 1>&2
}

info () {
    echo "$*" 1>&2
}

warning () {
    echo "warning: $*" 1>&2
}

usage () {
    info "usage: $0 [-p <pattern>] [-I <ignore-list>] -o <output> <inputs>"
    exit ${1:-1}
}

emit () {
    echo "$*" >> $OUTPUT
}


# set up defaults
PATTERN="^mrp_|^_mrp_"                # export everything prefixed with mrp_
IGNORE="MRP_PRINTF_LIKE,MRP_NULLTERM" # ignore these symbols/macros
IT=","                                # ignore-list is comma-separated
SOURCES=""                            # no default input, must be specified
OUTPUT=""                             # no default output, must be specified

# parse command line
while [ -n "${1#-}" ]; do
    case $1 in
        -o)
            if [ -z "$OUTPUT" ]; then
                shift
                OUTPUT="$1"
            else
                error "Multiple output files requested."
                usage
            fi
            ;;
        -p)
	    shift;
            PATTERN="$1"
            ;;
        -I)
            shift
            IGNORE="$IGNORE$IT$1"
	    IT=","
            ;;
        -h)
            usage 0
            ;;
	-q)
	    QUIET="yes"
	    ;;
        -c)
            # This is only for command-line compatibility with collect-symbols
            # to minimize the impact of switching back and forth (if needed).
            # collect-symbols gets compilation flags passed using the -c
            # option which we simply ignore here when using ctags.
            shift
            ;;
        -*)
            error "Unknown option '$1'."
            usage
            ;;
        *)
            SOURCES="$SOURCES $1"
            ;;
    esac
    shift
done

# check that we've got everything mandatory
if [ -z "$OUTPUT" ]; then
    error "No output file specified (use the -o option)."
    usage
fi

if [ -z "$SOURCES" ]; then
    warning "No input files, generating local-only linker script."
    emit "{"
    emit "    local:"
    emit "        *;"
    emit "};"
    exit 0
fi

if [ -z "$PATTERN" ]; then
    PATTERN="^mrp_"
fi

if [ -n "$IGNORE" ]; then
    ignore_opts="-I $IGNORE"
else
    ignore_opts=""
fi

# check that we have ctags
which ctags >& /dev/null
if [ "$?" != "0" ]; then
    error "Needs ctags to regenerate linker script $OUTPUT..."
    exit 1
fi

# generate the output
[ -n "$QUIET" ] || info "Generating linker script $OUTPUT..."
rm -f $OUTPUT
touch $OUTPUT

emit "{"
emit "    global:"
ctags $ignore_opts -f - --c-kinds=px $SOURCES | \
    awk "/$PATTERN/ { print \$1; }" | \
        sort | \
            while read sym; do
                emit "        $sym;"
            done

emit "    local:"
emit "        *;"
emit "};"
